package haoi.dt.thread;

import cn.hutool.core.io.FileUtil;
import haoi.dt.MainTest;
import haoi.dt.utils.*;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.HttpHostConnectException;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.security.cert.X509Certificate;
import java.io.File;
import java.io.IOException;
import java.net.SocketException;
import java.security.cert.CertificateException;
import java.util.Arrays;
import java.util.List;

public class AutoInviteCodeThread extends Thread {
    private String domainName = null;

    private String mobile;

    private String account;
    private String realName;

    private boolean next;
    public AutoInviteCodeThread(String domainName){
        this.domainName = domainName;

        //第一次初始化
        mobile = PhoneGen.getTel();
        account = AccountGen.getAccount();
        realName = ChineseRealNameGen.gen();
    }
    @Override
    public void run() {
        //这里是邀请码开始跑的位置  5是 开始跑的邀请码是 000005 跑到  1000000 -1 也就是 999999
        for(int begin = 47; begin < 1000000 ; begin++){
            //获取代理
            String hostPortStr = ProxyService.getProxy();

            String[] hostPortArr = hostPortStr.split(":");

            String host = hostPortArr[0];
            String port = hostPortArr[1];
            System.out.println("使用代理:"+hostPortStr);

            HttpClient client = getHttpClient(host,Integer.valueOf(port));
            String verifyCode = null;
            try {
                verifyCode = this.getVerifyCode(client);
            } catch (HttpHostConnectException e2){
                System.out.println("代理失效,重试");
                //重试当前失败
                begin = begin - 1;
                continue;
            } catch (SocketException e4){
                System.out.println("上传验证码到验证码平台异常,重试");
                begin = begin - 1;
                continue;
            } catch (IOException e) {
                e.printStackTrace();
                //重试当前失败
                begin = begin - 1;
                continue;
            }catch (Exception e3){
                //重试当前失败
                e3.printStackTrace();
                begin = begin - 1;
                continue;
            }

            if(verifyCode == null){
                begin = begin - 1;
                continue;
            }
            String sixNumber = NumberUtil.gen6(begin);
            String result = null;
            try {
                result = this.register(client,  verifyCode ,  sixNumber );

            } catch (IOException e) {
                e.printStackTrace();
                //重试当前失败
                begin = begin - 1;
                continue;
            } catch (InterruptedException e) {
                e.printStackTrace();
                //重试当前失败
                begin = begin - 1;
                continue;
            }
            if(result.contains("成功")){
                //打印成功信息
                System.out.println("邀请码:"+sixNumber + "，网址:" + domainName +",手机:"+mobile +",账户名:"+account+",真实姓名:"+realName+",密码:asd081623");
                //随机姓名 随机手机号
                next = true;
                continue;
            }else{
                next = false;
                if(result.contains("登录账号已经被占用")){
                    System.out.println("登录账号已经被占用," + this.account);
                    this.account = AccountGen.getAccount();
                    begin = begin -1 ;
                    continue;
                }else if(result.contains("此手机号码已经注册")){
                    System.out.println("此手机号码已经注册," + this.mobile);
                    this.mobile = PhoneGen.getTel();
                    begin = begin -1 ;
                    continue;
                }else if(result.contains("您填写的邀请码已失效")){
                    //不打印
                    System.out.println("您填写的邀请码已失效,"+sixNumber);
                }else if(result.contains("您填写的邀请码不正确")){
                    //不打印
                    System.out.println("您填写的邀请码不正确,"+sixNumber);
                }else if(result.contains("502 Bad Gateway")){
                    //502
                    System.out.println("网站拒绝提供服务,"+sixNumber);
                    begin = begin -1 ;
                    continue;
                }else if(result.contains("407 Proxy Authentication Required")){
                    //407
                    System.out.println("代理需要登录,重试,"+sixNumber);
                    begin = begin -1 ;
                    continue;
                }else if(result.contains("图形验证码错误")){
                    //图形验证码错误
                    System.out.println("图形验证码错误,重试,"+sixNumber);
                    begin = begin -1 ;
                    continue;
                }else{
                    System.out.println(result+",sixNumber"+sixNumber);
                }

            }


            //放慢脚步 防止被服务器发现 15s
//            try {
//                Thread.sleep(1000 * 15 );
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
        }
    }

    /**
     * 获取验证码
     * @param client
     * @return
     */
    public String getVerifyCode(HttpClient client) throws IOException {
        String verifyCodeUrl = domainName + "/api/User/GetAuthCode";
        HttpGet verifyCodeGet = new HttpGet(verifyCodeUrl);

        HttpResponse response = client.execute(verifyCodeGet);

        String filePath = System.currentTimeMillis()+".png";
        File file = new File(filePath);
        FileUtil.writeBytes(EntityUtils.toByteArray(response.getEntity()) , file);
        String responseStr = MainTest.sendFile(file.getAbsolutePath());
        String result = "";
        while(result.equals("")){
            //休息2秒
            try {
                Thread.sleep(1000 * 2 );
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            result = MainTest.getAnswer(responseStr);
        }
        return result;
    }

    /**
     *
     * @param client
     * @param verifyCode
     * @param inviteCode
     * @return
     * @throws IOException
     * @throws InterruptedException
     */
    public String register(HttpClient client , String verifyCode, String inviteCode ) throws IOException, InterruptedException {
        if(next){
            mobile = PhoneGen.getTel();
            account = AccountGen.getAccount();
            realName = ChineseRealNameGen.gen();
        }

        String registerUrl = domainName + "/api/User/Register";
        HttpPost httpPost =  new HttpPost(registerUrl);
        NameValuePair namePair = new BasicNameValuePair("mobile", mobile);
        NameValuePair passPair = new BasicNameValuePair("password","8f4a455501d4a8dd462a874186c34965");
        NameValuePair checkPassPair = new BasicNameValuePair("checkpwd","asd081623");
        NameValuePair cPassPair = new BasicNameValuePair("c_password","");
        NameValuePair agentCreatePair = new BasicNameValuePair("agent_create_ind","0");
        NameValuePair parentUserAgentPair = new BasicNameValuePair("parent_user_agent_id","");
        NameValuePair attr1Pair = new BasicNameValuePair("attr1","asd081623");
        NameValuePair attr2Pair = new BasicNameValuePair("attr2","");
        NameValuePair userTypePair = new BasicNameValuePair("USER_TYPE_CD","credit");
        NameValuePair registerAdrPair = new BasicNameValuePair("REGISTER_ADR",domainName+"/v/");
        NameValuePair inviteCodePair = new BasicNameValuePair("INVITE_CODE",inviteCode);
        NameValuePair realNamePair = new BasicNameValuePair("REAL_NAME",realName);
        NameValuePair loginAccountPair = new BasicNameValuePair("LOGIN_ACCOUNT",account);
        NameValuePair wechatPair = new BasicNameValuePair("WECHAT","");
        NameValuePair qqPair = new BasicNameValuePair("QQ","");
        NameValuePair emailPair = new BasicNameValuePair("EMAIL","");
        NameValuePair verifyCodePair = new BasicNameValuePair("code",verifyCode);
        NameValuePair smsCodePair = new BasicNameValuePair("smsCode","");
        NameValuePair loginWwwPair = new BasicNameValuePair("login_www",domainName+"/v");
        NameValuePair jmpPair = new BasicNameValuePair("jmptwo","1");
        List<NameValuePair> pairs = Arrays.asList(namePair , passPair , checkPassPair , cPassPair , agentCreatePair , parentUserAgentPair , attr1Pair , attr2Pair
                ,userTypePair , registerAdrPair , inviteCodePair , realNamePair , loginAccountPair , wechatPair , qqPair , emailPair , verifyCodePair,
                smsCodePair,loginWwwPair,jmpPair);

        //设置请求头
        httpPost.addHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0");
        httpPost.addHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
        httpPost.addHeader("Referer",domainName+"/v/");
        UrlEncodedFormEntity postEntity = new UrlEncodedFormEntity(pairs);
        httpPost.setEntity(postEntity);
        HttpResponse httpResponse = client.execute(httpPost);

        int code = httpResponse.getStatusLine().getStatusCode();



        String result = EntityUtils.toString(httpResponse.getEntity());
        //403错误 禁止访问
        if(code == 403){
            //休眠 30秒
            System.out.println("检测到服务器强制阻断连接,主动退出休眠5分钟");
            Thread.sleep(1000 * 60 * 5);
        }
        return result;
    }


    private static CloseableHttpClient getHttpClient(String host,int port) {
        HttpHost proxy = new HttpHost(host, port, "http");
        //把代理设置到请求配置
        RequestConfig defaultRequestConfig = RequestConfig.custom()
                .setProxy(proxy)
                .build();
        CloseableHttpClient httpclient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();
        return httpclient;
    }

    private static CloseableHttpClient getHttpsClient(String qlb) {
        //这里设置客户端不检测服务器ssl证书
        try {
            X509TrustManager x509mgr = new X509TrustManager() {
                public void checkClientTrusted(X509Certificate[] xcs, String string) {
                }
                public void checkServerTrusted(X509Certificate[] xcs, String string) {
                }

                public void checkClientTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws CertificateException {

                }

                public void checkServerTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws CertificateException {

                }

                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            };
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, new TrustManager[] { x509mgr }, null);
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            HttpHost proxy = new HttpHost(qlb, 443, "https");
            RequestConfig defaultRequestConfig = RequestConfig.custom()
                    .setProxy(proxy)
                    .build();
            CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultRequestConfig(defaultRequestConfig).build();
            return httpclient;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
